package com.kinghood.productcenter.manager.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kinghood.infrastructure.api.authority.SysLogModuleEnum;
import com.kinghood.infrastructure.model.KingHoodException;
import com.kinghood.infrastructure.model.KingHoodExceptionUtil;
import com.kinghood.infrastructure.model.KingHoodResponseVO;
import com.kinghood.infrastructure.util.UserUtil;
import com.kinghood.infrastructure.util.base.IdGenUtil;
import com.kinghood.infrastructure.util.excel.EasyExcelUtil;
import com.kinghood.infrastructure.util.excel.ExcelExportWriter;
import com.kinghood.obs.ObsManger;
import com.kinghood.productcenter.common.model.dao.product.DownloadCenterDO;
import com.kinghood.productcenter.common.model.dto.base.ListProductQueryDTO;
import com.kinghood.productcenter.common.model.dto.base.SaveFileLocallyDTO;
import com.kinghood.productcenter.common.model.dto.product.*;
import com.kinghood.productcenter.common.model.vo.product.ProductAttributeListVO;
import com.kinghood.productcenter.common.model.vo.product.ProductDetailVO;
import com.kinghood.productcenter.common.model.vo.product.ProductListVO;
import com.kinghood.productcenter.common.model.vo.product.ProductTemplateInfoVO;
import com.kinghood.productcenter.common.properties.BaseProperties;
import com.kinghood.productcenter.manager.IProductBaseManager;
import com.kinghood.productcenter.service.async.IAsyncHuaWeiYunService;
import com.kinghood.productcenter.service.async.IAsyncZipService;
import com.kinghood.productcenter.service.base.IBaseAttributeService;
import com.kinghood.productcenter.service.base.IBaseProductTemplateService;
import com.kinghood.productcenter.service.product.IDownloadCenterService;
import com.kinghood.productcenter.service.product.IProductAttributeService;
import com.kinghood.productcenter.service.product.IProductBaseService;
import com.kinghood.productcenter.service.product.handler.ProductBaseHandler;
import com.kinghood.sharding.model.BasePage;
import com.kinghood.sharding.model.KingPageResult;
import com.kinghood.sharding.model.PageResponseVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StopWatch;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

@RequiredArgsConstructor
@Slf4j
@Service
public class ProductBaseManager implements IProductBaseManager {

    @Resource
    private IProductBaseService productBaseService;
    private final BaseProperties baseProperties;
    private final IProductAttributeService productAttributeService;
    private final IBaseProductTemplateService productTemplateService;
    private final String uploadPath = "/app/file";
    @Value("${obs.prefixUrl}")
    private String prefixUrl;
    private final IDownloadCenterService downloadCenterService;
    private final IAsyncHuaWeiYunService asyncUploadHuaWeiYun;
    private final IAsyncZipService asyncZip;
    private final IBaseAttributeService attributeService;
    private final ObsManger obsManger;


    /**
     * 列表产品
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/22
     */
    @Override
    public PageResponseVO listProduct(ListProductQueryDTO param) {
        Page<ProductListVO> result = productBaseService.listProduct(param);

        if (CollectionUtils.isNotEmpty(param.getShowAttributeList()) && result.getRecords().size() > 0) {
            JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(result.getRecords()));
            List<JSONObject> arrResult = new ArrayList<>();
            List<Long> productList = result.getRecords().stream().map(m -> m.getId()).collect(Collectors.toList());
            // 查询出属性
            Map<Long, List<ProductAttributeListVO>> attributeListVOMap =
                    productAttributeService.getProductAttributeByCode(param.getShowAttributeList(), productList);
            for (int i = 0; i < jsonArray.size(); i++) {
                // 把属性放入对象中
                List<ProductAttributeListVO> attributeListVOS = attributeListVOMap.get(jsonArray.getJSONObject(i).getLong("id"));
                if (CollectionUtils.isNotEmpty(attributeListVOS)) {
                    for (ProductAttributeListVO attribute : attributeListVOS) {
                        jsonArray.getJSONObject(i).put(attribute.getCode(), attribute.getValue());
                    }
                }
                arrResult.add(jsonArray.getJSONObject(i));
            }
            Page<JSONObject> arrayPage = new Page<>();
            arrayPage.setCurrent(result.getCurrent());
            arrayPage.setPages(result.getPages());
            arrayPage.setTotal(result.getTotal());
            arrayPage.setRecords(arrResult);
            return KingPageResult.getResult(arrayPage);
        }
        return KingPageResult.getResult(result);
    }

    @Override
    public ProductDetailVO getProduct(GetProductReqDTO in) {

        // 商品数据
        ProductDTO product = null;
        if (Objects.nonNull(in.getProductId())) {
            product = productBaseService.getProduct(in.getProductId());
            KingHoodExceptionUtil.isNull(product, "商品不存在");
            if(Objects.isNull(in.getProductTemplateId())){
                in.setProductTemplateId(product.getProductTemplateId());
            }
        }

        // 模板
        ProductDetailVO res = new ProductDetailVO();
        ProductTemplateInfoVO template = productTemplateService.getProductTemplateById(in.getProductTemplateId(),true);
        res.setProductTemplateId(template.getProductTemplateId());
        res.setNodeList(template.getNodeList());
        res.setDefaultSupplierId(template.getSupplierId());
        res.setSkuStatus(template.getSkuStatus());

        // 将商品的value数据封装模板
        if (Objects.nonNull(product)) {
            ProductBaseHandler.handleProductTemplateData(res, product);
        } else {
            // 默认有系统字段的默认值
            res.setStyleName(template.getStyleName());
            res.setStatus(template.getStyleStatus());
        }

        return res;
    }

    @Override
    public List<Map<String, String>> importData(MultipartFile file) {

        // 基础dao数据
        BaseProductDaoDTO dao = productBaseService.getBaseProductDao();
        dao.handleMap();
        List<Map<String, String>> res = new ArrayList<>();
        try {
            CountDownLatch latch = new CountDownLatch(1);

            EasyExcel.read(file.getInputStream(), new AnalysisEventListener<Map<Integer, String>>() {

                private static final int BATCH_COUNT = 100;
                private List<Map<Integer, String>> cachedDataList = new ArrayList<>(BATCH_COUNT);
                private Map<Integer, ProductExcelAttributeDTO> headCodeMap;

                @Override
                public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
                    log.info("头行数据：{}", headMap);
                    headCodeMap = ProductBaseHandler.checkExcelHead(headMap, dao, false);
                }

                @Override
                public void invoke(Map<Integer, String> data, AnalysisContext context) {
                    ReadRowHolder readRowHolder = context.readRowHolder();
                    Integer rowIndex = readRowHolder.getRowIndex();
                    log.info("第{}行数据:{}", rowIndex, data);
                    cachedDataList.add(data);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {

                    List<Map<String, String>> maps = productBaseService.handleImportData(cachedDataList, headCodeMap,dao);
                    res.addAll(maps);
                    latch.countDown();
                }

            }).sheet().doRead();

            latch.await();
        } catch (KingHoodException kingHoodException) {
            KingHoodExceptionUtil.throwException(kingHoodException.getMessage());
        } catch (Exception e) {
            log.error("导入数据出现异常", e);
            KingHoodExceptionUtil.throwException("导入数据出现异常");
        }

        return res;
    }

    /**
     * 本地备份数据
     */
    public SaveFileLocallyDTO saveFileLocally(Integer module,MultipartFile file, String fileName, String size) throws IOException {

        SaveFileLocallyDTO res = new SaveFileLocallyDTO();
        if (!Objects.equals(baseProperties.getUpload(), Boolean.TRUE)) {
            res.setInputStream(file.getInputStream());
            return res;
        }
        String uploadDir = baseProperties.getUploadPath();
        File uploadDirFile = new File(uploadDir);
        if (!uploadDirFile.exists()) {
            uploadDirFile.mkdir();
        }
        String filePath = uploadDir + File.separator + fileName + ".xlsx";
        File dest = new File(filePath);
        file.transferTo(dest);

        Long downloadId = downloadCenterService.addUploadFile(module, 1, fileName + ".xlsx", size, filePath);
        res.setDownloadId(downloadId);
        res.setFilePath(filePath);
        res.setInputStream(new FileInputStream(dest));
        return res;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void uploadProduct(MultipartFile file, HttpServletResponse response) {

        long size = file.getSize();
        String sizeName = ProductBaseHandler.getSizeName(size);

        Long userId = UserUtil.getUserId();
        // 导入
        List<Map<Integer, String>> result = new ArrayList<>();
        StopWatch w = new StopWatch();
        w.start("基础dao数据");
        // 基础dao数据
        BaseProductDaoDTO dao = productBaseService.getBaseProductDao();
        dao.handleMap();
        w.stop();

        try {

            CountDownLatch latch = new CountDownLatch(1);

            String fileName = file.getOriginalFilename();
            String finalFileName = fileName;
            if (!StringUtils.isEmpty(fileName) && fileName.contains(".")) {
                finalFileName = fileName.substring(0, fileName.indexOf("."))
                        + DateUtil.format(new Date(), "yyyy-MM-dd_HH_mm_ss");
            } else {
                finalFileName = fileName + DateUtil.format(new Date(), "yyyy-MM-dd_HH_mm_ss");
            }
            log.info("文件名：{}，文件大小：{}", finalFileName, sizeName);
            w.start("本地备份");
            SaveFileLocallyDTO saveFileLocallyDTO = saveFileLocally(SysLogModuleEnum.Type.PRODUCT_PRODUCT,file, finalFileName, sizeName);
            w.stop();
            w.start("处理Excel数据");
            Map<Integer, String> head = new HashMap<>();
            EasyExcel.read(saveFileLocallyDTO.getInputStream(), new AnalysisEventListener<Map<Integer, String>>() {
                private static final int BATCH_COUNT = 100;
                private List<Map<Integer, String>> cachedDataList = new ArrayList<>(BATCH_COUNT + 20);
                private String last;
                private Map<String, Integer> fieldMap;
                private Map<Integer, ProductExcelAttributeDTO> headCodeMap;
                private RowFieldRecordDTO rowFieldRecord;

                @Override
                public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
                    log.info("头行数据：{}", headMap);
                    head.putAll(headMap);
                    fieldMap = new HashMap<>(headMap.size());
                    headMap.forEach((x, y) -> {
                        fieldMap.put(y, x);
                    });
                    headCodeMap = ProductBaseHandler.checkExcelHead(headMap, dao, true);
                    rowFieldRecord = ProductBaseHandler.handleHeadCode(headCodeMap);
                    rowFieldRecord.setUserId(userId);
                }

                @Override
                public void invoke(Map<Integer, String> data, AnalysisContext context) {
                    ReadRowHolder readRowHolder = context.readRowHolder();
                    Integer rowIndex = readRowHolder.getRowIndex();
                    log.info("第{}行数据:{}", rowIndex, data);
                    // 如果数据都是空的，忽略
                    long count = data.values().stream().filter(org.apache.commons.lang3.StringUtils::isNotBlank).count();
                    if (count == 0) {
                        return;
                    }

                    Integer styleNumberIndex = fieldMap.get("款号");
                    String styleNumber = data.get(styleNumberIndex);
                    if (cachedDataList.size() >= BATCH_COUNT && !Objects.equals(last, styleNumber)) {
                        // 处理一批数据
                        List<Map<Integer, String>> maps = productBaseService.handleExcelData(cachedDataList, headCodeMap, dao,
                                rowFieldRecord);
                        if (CollectionUtils.isNotEmpty(maps)) {
                            result.addAll(maps);
                        }
                        cachedDataList = new ArrayList<>(BATCH_COUNT + 20);
                    }
                    last = styleNumber;
                    cachedDataList.add(data);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    List<Map<Integer, String>> maps = productBaseService.handleExcelData(cachedDataList, headCodeMap, dao, rowFieldRecord);
                    if (CollectionUtils.isNotEmpty(maps)) {
                        result.addAll(maps);
                    }
                    log.info("excel数据读取结束");
                    latch.countDown();
                }

            }).sheet().doRead();

            latch.await();

            w.stop();
            log.info(w.prettyPrint());
            // 导出
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String exportName = URLEncoder.encode(finalFileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + exportName + ".xlsx");
//            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="  + exportName + ".xlsx");

            EasyExcel.write(response.getOutputStream())
//                    .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 20, (short) 100))
//                    .autoCloseStream(Boolean.FALSE)
                    .head(ProductBaseHandler.head(head))
                    .sheet("结果")
                    .doWrite(ProductBaseHandler.dataList(result));

            if(Objects.nonNull(saveFileLocallyDTO.getDownloadId())){
                asyncUploadHuaWeiYun.uploadToHuaWeiYun(saveFileLocallyDTO.getDownloadId(), saveFileLocallyDTO.getFilePath());
            }
        } catch (KingHoodException kingHoodException) {
            KingHoodExceptionUtil.throwException(kingHoodException.getMessage());
        } catch (Exception e) {
            log.error("excel文件读取失败：", e);
            KingHoodExceptionUtil.throwException("excel文件读取失败");
        }
    }


    /**
     * todo: 数据量大，要异步下载数据 导出产品
     *
     * @param param    参数
     * @param response 回答
     * @author jp
     * @date 2023/12/25
     */
    @Override
    public void exportProduct(ListProductQueryDTO param, HttpServletResponse response) {
        String fileName = StringUtils.isEmpty(param.getFileName()) ? "款式数据" : param.getFileName();
        String sheetName = StringUtils.isEmpty(param.getSheetName()) ? "款式" : param.getSheetName();

        if (Objects.isNull(param.getPage())) {
            param.setPage(new BasePage());
            param.getPage().setPageSize(9999l);
        }
        Page<ProductListVO> result = productBaseService.listProduct(param);
        Map<Long, Map<String, ProductAttributeListVO>> attributeListVOMap = null;
        if (param.downloadFieldHasAttribute() && result.getTotal() > 0) {
            List<Long> productList = result.getRecords().stream().map(m -> m.getId()).collect(Collectors.toList());
            // 查询出属性
            attributeListVOMap = productAttributeService.getAllAttributeByCode(param.getRealAttribute(), productList);
        }
        // 要下载的属性code和名称
        Map<String, String> attributeMap = new HashMap<>();
        if (!param.getRealAttribute().isEmpty()) {
            attributeMap = attributeService.getCodeNameMap(param.getRealAttribute());
        }
        ExcelExportWriter exportWriter = new ExcelExportWriter();
        try {
            // 设置文件名
            exportWriter.setSheetName(sheetName);
            exportWriter.setFileName(fileName);

            // 设置内容
            List<List> dataList = new ArrayList<>();
            boolean setHead = true;
            short height = 15;
            for (ProductListVO record : result.getRecords()) {
                if (setHead) {
                    // 设置标题
                    List<String> heads = new ArrayList<>();
                    // 商品基础属性
                    for (String baseField : param.getDownloadBaseField()) {
                        String[] annotion = record.getClass().getDeclaredField(baseField).getAnnotation(ExcelProperty.class).value();
                        heads.add(annotion[0]);
                    }
                    // 动态属性标题
                    if (!org.springframework.util.CollectionUtils.isEmpty(attributeMap)) {
                        for (String attribute : param.getRealAttribute()) {
                            if (Objects.nonNull(attributeMap.get(attribute))) {
                                heads.add(Optional.ofNullable(attributeListVOMap.get(record.getId()))
                                        .map(i -> i.get(attribute))
                                        .map(ProductAttributeListVO::getName).orElse(attributeMap.get(attribute)));
                            }
                        }
                    }
                    exportWriter.setOneLineHeads(heads);
                    setHead = false;
                }

                List<Object> columData = new ArrayList<>();
                // 商品基础属性
                for (String baseField : param.getDownloadBaseField()) {
                    // 获取对象的属性
                    Field nameField = record.getClass().getDeclaredField(baseField);
                    nameField.setAccessible(true);
                    // 获取对象的属性值
                    Object baseValue = nameField.get(record);
                    // 图片要特殊处理
                    if (baseField.equals("picture")) {
                        if (StringUtils.isEmpty(baseValue)) {
                            columData.add("");
                        } else {
                            try {
                                columData.add(new URL(prefixUrl + baseValue + "?x-image-process=image/resize,m_lfit,h_100"));
                                height = 100;
                            } catch (MalformedURLException e) {
                                columData.add("");
                                log.error("华为obs图片获取失败:", e);
                            }
                        }
                    } else {
                        columData.add(baseValue);
                    }
                }
                // 商品动态属性
                if (!org.springframework.util.CollectionUtils.isEmpty(attributeListVOMap)) {
                    for (String attribute : param.getRealAttribute()) {
                        if (Objects.nonNull(attributeMap.get(attribute))) {
                            columData.add(Optional.ofNullable(attributeListVOMap.get(record.getId()))
                                    .map(i -> i.get(attribute))
                                    .map(ProductAttributeListVO::getValue).orElse(""));
                        }
                    }
                }
                dataList.add(columData);
            }
            exportWriter.setDatas(dataList);
            String path = EasyExcelUtil.exportDynamic(response, exportWriter, height, uploadPath);
            DownloadCenterDO downloadCenterDO = new DownloadCenterDO();
            File file = new File(path);
            LocalDateTime now = LocalDateTime.now();
            downloadCenterDO.setId(IdGenUtil.getId())
                    .setFileName(file.getName())
                    .setModule(SysLogModuleEnum.PRODUCT_PRODUCT.getType())
                    .setType(2)
                    .setFileSize(ProductBaseHandler.getSizeName(file.length()))
                    .setUrl(path)
                    .setCreateTime(now)
                    .setUpdateTime(now)
                    .setCreateUserId(UserUtil.getUserId())
                    .setUpdateUserId(UserUtil.getUserId());
            downloadCenterService.save(downloadCenterDO);
            asyncUploadHuaWeiYun.uploadToHuaWeiYun(downloadCenterDO.getId(), file.getAbsolutePath());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * todo 待优化，上传产品图片
     *
     * @param uploadFile 文件
     * @param response   回答
     * @author jp
     * @date 2023/12/28
     */
    @Override
    public void uploadProductPicture(MultipartFile uploadFile, String type, HttpServletResponse response) {
        List<ProductPictureNotExistDTO> errorMessage = new ArrayList<>();
        List<String> existProductCodeList;
        LocalDateTime now = LocalDateTime.now();
        Set<String> productCodeList = new HashSet<>();
        List<String> originProductCodeList = new ArrayList<>();
        if (!uploadFile.getOriginalFilename().endsWith("zip") && !uploadFile.getOriginalFilename().endsWith("7z")) {
            throw new KingHoodException(-1, "只支持zip、7z格式压缩包");
        }

        String newFileName = createFileName(uploadFile);

        // 获取年月日的日期格式
        DateTimeFormatter pathDate = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = pathDate.format(LocalDateTime.now());

        File readPath = createReadPath(format);

        // 文件真实的保存路径
        File file = new File(readPath.getAbsolutePath() + File.separator + newFileName);

        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            // 把文件保存到本地
            uploadFile.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (uploadFile.getOriginalFilename().endsWith("zip")) {
            readZipData(productCodeList, originProductCodeList, uploadFile);
        } else if (uploadFile.getOriginalFilename().endsWith("7z")) {
            read7zData(productCodeList, originProductCodeList, file);
        }

        existProductCodeList = this.productBaseService.getCodeByList(productCodeList);
        if (CollectionUtils.isEmpty(existProductCodeList)) {
            if (file.exists()) {
                boolean deleted = file.delete();
                log.info("已成功删除文件：" + file.getAbsolutePath() + ", 结果：" + deleted);
            }
            throw new KingHoodException(-1, "无存在的款式编码");
        }
        productCodeList.retainAll(existProductCodeList);
        // 有不存在的款号，也有存在的款号
        if (CollectionUtils.isNotEmpty(productCodeList)) {
            for (String picName : originProductCodeList) {
                String name = getPictureName(picName);
                if (!productCodeList.contains(name)) {
                    ProductPictureNotExistDTO error = new ProductPictureNotExistDTO();
                    error.setCode(picName);
                    error.setRemark(name + "款号不存在");
                    errorMessage.add(error);
                }
            }
        }
        try {
            if (CollectionUtils.isNotEmpty(errorMessage)) {
                EasyExcelUtil.export(response, "图片导入结果", "款号", errorMessage, ProductPictureNotExistDTO.class, null, null);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 文件保存到数据库中
        DownloadCenterDO downloadCenterDO = new DownloadCenterDO();
        downloadCenterDO.setId(IdGenUtil.getId())
                .setFileName(newFileName)
                .setModule(SysLogModuleEnum.PRODUCT_PRODUCT.getType())
                .setType(1)
                .setFileSize(ProductBaseHandler.getSizeName(file.length()))
                .setUrl(uploadPath + File.separator + format + File.separator + newFileName)
                .setCreateTime(now)
                .setUpdateTime(now)
                .setCreateUserId(UserUtil.getUserId())
                .setUpdateUserId(UserUtil.getUserId());
        downloadCenterService.save(downloadCenterDO);
        asyncZip.uploadPicToHuaWeiYun(file.getAbsolutePath(), existProductCodeList, readPath.getPath(), type, UserUtil.getUserId(), downloadCenterDO.getId());
    }

    /**
     * 创建文件名
     *
     * @param uploadFile 上传档案
     * @return @return {@link String }
     * @author jp
     * @date 2024/01/24 14:14
     */
    private String createFileName(MultipartFile uploadFile) {
        // 获取文件名
        String fileName = uploadFile.getOriginalFilename();
        log.info("上传文件原始的名字: " + fileName);

        // 使用uuid生成新文件名
        DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyMMddHHmmss");
        String dataStr = dtf2.format(LocalDateTime.now());
        String newFileName = fileName.substring(0, fileName.lastIndexOf("."))
                + dataStr
                + fileName.substring(fileName.lastIndexOf("."), fileName.length());
        log.info("保存的文件的新名字: " + newFileName);
        return newFileName;
    }

    /**
     * 创建读取路径
     *
     * @param format 总体安排
     * @return @return {@link File }
     * @author jp
     * @date 2024/01/24 14:15
     */
    private File createReadPath(String format) {
        // 生成以日期分割的文件路径
        File readPath = new File(uploadPath + File.separator + format);
        log.info("存放的文件夹: " + readPath);
        String absolutePath = readPath.getAbsolutePath();
        log.info("存放文件的绝对路径: " + absolutePath);
        // 判断文件夹是否存在
        if (!readPath.isDirectory()) {
            // 创建文件夹
            readPath.mkdirs();
        }
        return readPath;
    }

    private void read7zData(Set<String> productCodeList, List<String> originProductCodeList, File file) {
        try {
            SevenZFile sevenZFile = new SevenZFile(file);
            final Iterable<SevenZArchiveEntry> entries = sevenZFile.getEntries();
            for (SevenZArchiveEntry entry : entries) {
                log.info("文件名：" + entry.getName() + " 文件大小：" + entry.getSize() + " bytes");
                productCodeList.add(getPictureName(entry.getName()));
                originProductCodeList.add(entry.getName());
            }
            sevenZFile.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void readZipData(Set<String> productCodeList, List<String> originProductCodeList, MultipartFile uploadFile) {
        try {
            //获取ZIP输入流(一定要指定字符集Charset.forName("GBK")否则会报java.lang.IllegalArgumentException: MALFORMED)
            ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(uploadFile.getInputStream()), Charset.forName("GBK"
            ));

            //定义ZipEntry置为null,避免由于重复调用zipInputStream.getNextEntry造成的不必要的问题
            ZipEntry ze = null;
            //循环遍历
            while ((ze = zipInputStream.getNextEntry()) != null) {
                log.info("文件名：" + ze.getName() + " 文件大小：" + ze.getSize() + " bytes");
                productCodeList.add(getPictureName(ze.getName()));
                originProductCodeList.add(ze.getName());
            }
            //一定记得关闭流
            zipInputStream.closeEntry();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取图片名称
     *
     * @param picture 相片
     * @return @return {@link String }
     * @author jp
     * @date 2024/01/24 11:03
     */
    private String getPictureName(String picture) {
        String name;
        if (!picture.contains("-")) {
            name = picture.substring(0, picture.lastIndexOf("."));
        } else {
            String endStr = picture.substring(picture.lastIndexOf("-")+1, picture.lastIndexOf("."));
            if (!isNumeric(endStr)) {
                name = picture.substring(0, picture.lastIndexOf("."));
            } else {
                name = picture.substring(0, picture.lastIndexOf("-"));
            }
        }
        return name;
    }

    public static boolean isNumeric(String str) {
        // Check if the string is null or empty
        if (str == null || str.isEmpty()) {
            return false;
        }

        // Iterate over each character in the string
        for (char c : str.toCharArray()) {
            // Check if the character is a digit
            if (!Character.isDigit(c)) {
                return false;
            }
        }

        // If all characters are digits, return true
        return true;
    }

    /**
     * 导口产品图片
     *
     * @param param 参数
     * @return @return {@link PageResponseVO }
     * @author jp
     * @date 2024/01/25 15:29
     */
    @Override
    public KingHoodResponseVO exportProductPicture(ListProductQueryDTO param) {
        if (Objects.isNull(param.getPage())) {
            param.setPage(new BasePage());
            param.getPage().setPageSize(10L);
        }
        Page<ProductListVO> result = productBaseService.listProduct(param);
        if (result.getTotal() == 0) {
            return KingHoodResponseVO.fail("无数据可导出");
        }
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyMMddHHmmss");
        String dataStr = dtf2.format(LocalDateTime.now());
        String newFileName = "款式图片批量下载"
                + dataStr
                + ".zip";
        DownloadCenterDO downloadCenterDO = new DownloadCenterDO();
        downloadCenterDO.setId(IdGenUtil.getId())
                .setFileName(newFileName)
                .setModule(SysLogModuleEnum.PRODUCT_PRODUCT.getType())
                .setType(2)
                .setStatus(2)
                .setCreateTime(now)
                .setUpdateTime(now)
                .setCreateUserId(UserUtil.getUserId())
                .setUpdateUserId(UserUtil.getUserId());
        downloadCenterService.save(downloadCenterDO);
        asyncZip.asyncExportProductPicture(param, downloadCenterDO);
        return KingHoodResponseVO.success("稍后前往下载中心下载");
    }
}
